package flex.cc.single.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;

import flex.cc.common.utils.*;
import flex.cc.drive.dto.DriverInterfaceLogEntity;
import flex.cc.drive.dto.DriverRemarkEntity;
import flex.cc.drive.dto.OrderDriverEntity;
import flex.cc.single.dto.vo.SingleOrderVo;
import flex.cc.store.dto.entity.StoreInfoEntity;
import flex.cc.store.dto.vo.StoreInfoVo;
import flex.cc.store.service.StoreCouponService;
import flex.cc.store.service.StoreInfoService;
import flex.cc.system.entity.DictCodeEntity;
import flex.cc.system.service.DictCodeService;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.core.utils.RequestUtil;
import flex.cc.drive.util.DriveDESUtil;
import flex.cc.single.dao.SingleCouponTrackDao;
import flex.cc.single.dao.SingleOrderDao;
import flex.cc.single.dao.SingleRecordDao;
import flex.cc.single.dto.entity.SingleCouponTrackEntity;
import flex.cc.single.dto.entity.SingleOrderEntity;
import flex.cc.single.dto.entity.SingleRecordEntity;
import flex.cc.single.service.AppointmentService;
import flex.cc.store.dao.StoreCouponDao;
import flex.cc.store.dto.entity.StoreCouponEntity;
import flex.cc.store.dto.vo.MsgConstant;
import flex.cc.util.APIConfigUtil;

/**
 * @author R
 * 2022年04月6日 13:06:01
 * @desc 预约实现层
 */
@Service("appointmentService")
public class AppointmentServiceImpl implements AppointmentService {
	private static final Logger logger = LoggerFactory.getLogger(AppointmentServiceImpl.class);

    @Autowired
    private SingleOrderDao singleOrderDao;
    @Autowired
    private StoreCouponDao storeCouponDao;
    @Autowired
	private APIConfigUtil apiConfigUtil;
    @Resource
    private SingleRecordDao singleRecordDao;
    @Resource
    private SingleCouponTrackDao singleCouponTrackDao;
    @Autowired
	private StoreCouponService storeCouponService;
    @Resource
	private StoreInfoService storeInfoService;
    @Autowired
	private DictCodeService dictCodeService;
	@Autowired
	private OrderNoGenerateUtil orderNoGenerateUtil;

    /**
     * @description 单项代驾类预约提交
     * @author R
     * @time 2022年04月6日 13:06:01
     * @param requestBodyMap 预约信息
     */
    @Override
    public JSONObject createDriverAppointment(Map<String, Object> requestBodyMap) {
		JSONObject jsonResult = new JSONObject();
		Map<String, Object> dataMap = new HashMap<String, Object>();
		Map<String, Object> requestMap = new HashMap<String, Object>();
		try {
			//归属卡券码
			String couponNum = (String) requestBodyMap.get("couponNum");
			StoreCouponEntity storeCouponEntity = storeCouponDao.queryByCouponNum(couponNum);
			dataMap.put("orderId", couponNum);
			
			//控制该接口是新增预约还是修改预约接口
			String requestType = (String) requestBodyMap.get("requestType");
			dataMap.put("requestType", requestType);	
			
			//车牌号
			String carNumber = (String) requestBodyMap.get("carNo");
			logger.info("预约代驾单下单接口接口:carNumber ==> {}", carNumber);
			if(PublicUtil.isEmpty(carNumber)) {
	    		logger.error("车牌号不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "车牌号不能为空");
	            return jsonResult;
			}
			
			//用户名
			String userName = (String) requestBodyMap.get("contacts");
			if(PublicUtil.isEmpty(userName)) {
	    		logger.error("用户名不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "用户名不能为空");
	            return jsonResult;
			}
			dataMap.put("userName", userName);
			//联系电话
			String telphone = (String) requestBodyMap.get("tel");
			if(PublicUtil.isEmpty(telphone)) {
	    		logger.error("联系电话不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "联系电话不能为空");
	            return jsonResult;
			}
			dataMap.put("telphone", telphone);

			dataMap.put("telphone", telphone);
			//预约时间
			String bespeakTime = (String) requestBodyMap.get("appointTime");
			if(PublicUtil.isEmpty(bespeakTime)) {
	    		logger.error("预约时间不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "预约时间不能为空");
	            return jsonResult;
			}
			dataMap.put("bespeakTime", bespeakTime);
			//起始地经度
			String longitude = (String) requestBodyMap.get("longitude");
			if(PublicUtil.isEmpty(longitude)) {
	    		logger.error("起始地经度不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "出发地经度不能为空");
	            return jsonResult;
			}	
			dataMap.put("longitude", longitude);
			//起始地纬度
			String latitude = (String) requestBodyMap.get("latitude");
			if(PublicUtil.isEmpty(latitude)) {
	    		logger.error("起始地纬度不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "出发地纬度不能为空");
	            return jsonResult;
			}		
			dataMap.put("latitude", latitude);
			//目的地经度
			String deLongitude = (String) requestBodyMap.get("deLongitude");
			if(PublicUtil.isEmpty(deLongitude)) {
	    		logger.error("目的地经度不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "目的地经度不能为空");
	            return jsonResult;
			}
			dataMap.put("deLongitude", deLongitude);
			//目的地纬度
			String deLatitude = (String) requestBodyMap.get("deLatitude");
			if(PublicUtil.isEmpty(deLatitude)) {
	    		logger.error("目的地纬度不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "目的地纬度不能为空");
	            return jsonResult;
			}		
			dataMap.put("deLatitude", deLatitude);
			//出发地省
			String departureProvince = (String) requestBodyMap.get("departureProvince");
			//出发地市
			String departureCity = (String) requestBodyMap.get("departureCity");
			dataMap.put("city", departureCity);
			//出发地区
			String departureArea = (String) requestBodyMap.get("departureArea");
			//目的地省
			String destinationProvince = (String) requestBodyMap.get("destinationProvince");
			//目的地市
			String destinationCity = (String) requestBodyMap.get("destinationCity");
			//目的地区
			String destinationArea = (String) requestBodyMap.get("destinationArea");

			//归属服务包
			String packageCode = (String) requestBodyMap.get("packageCode");
			
			//系统默认酒后代驾  需要传递出发地详细地址和目的地详细地址
			//出发地
			String startAddress = (String) requestBodyMap.get("departure");
			if(PublicUtil.isEmpty(startAddress)) {
	    		logger.error("上车地址不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "上车地址不能为空");
	            return jsonResult;
			}
			dataMap.put("startAddress", startAddress);
			//目的地
			String endAddress = (String) requestBodyMap.get("destination");
			if(PublicUtil.isEmpty(endAddress)) {
	    		logger.error("下车地址不能为空");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "下车地址不能为空");
	            return jsonResult;
			}
			dataMap.put("endAddress", endAddress);
			

			
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("couponNum", couponNum);
			StoreCouponEntity couponEntity = storeCouponDao.getOneByParams(params);
			String provider = couponEntity.getServer();
			
			String source = apiConfigUtil.getApiConfig(provider, "disponse_code");
			dataMap.put("source", source);
			
			

			logger.info(new Date() + "==" + dataMap.toString());
			
			//现根据卡券编码 查询是否存在服务单
			//卡券取消可用后 再次进行预约 依然对该条数据进行处理
			Map<String, Object> paramsMap = new HashMap<String, Object>();
			paramsMap.put("orderId", couponNum);
			SingleOrderEntity singleOrderEntity = singleOrderDao.getOneByParams(paramsMap);
			String orderNo = singleOrderEntity.getOrderNo();
			//服务单初始化状态  防止已派单或者预约成功 再次预约 下游会返回失败 再次更新服务单状态
			String initStatus = singleOrderEntity==null?null:singleOrderEntity.getStatus();
			if(PublicUtil.isNotEmpty(initStatus)&&initStatus.equals("02")) {
	    		logger.error("服务单已派单，无需再次预约");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "服务单已派单，无法再次预约");
	            return jsonResult;
			}		
			if(PublicUtil.isNotEmpty(initStatus)&&initStatus.equals("03")) {
	    		logger.error("服务单指派司机已到达，无需再次预约");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "服务单指派司机已到达，无法再次预约");
	            return jsonResult;
			}
			if(PublicUtil.isNotEmpty(initStatus)&&initStatus.equals("04")) {
	    		logger.error("服务单服务已完成，无需再次预约");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "服务单服务已完成，无法再次预约");
	            return jsonResult;
			}
			if(PublicUtil.isNotEmpty(initStatus)&&initStatus.equals("06")) {
	    		logger.error("服务单已核销取消，无需再次预约");
	    		jsonResult.put("resultCode", "01");
	    		jsonResult.put("resultDesc", "服务单已核销取消，无法再次预约");
	            return jsonResult;
			}
			
			//联系人
			singleOrderEntity.setContacts(userName);
			//联系电话
			singleOrderEntity.setTel(telphone);
			//车牌号
			singleOrderEntity.setCarNo(carNumber);
			//预约时间
			singleOrderEntity.setAppointTime(DateUtil.parseStringToDate(bespeakTime, "yyyy-MM-dd HH:mm:ss"));
			//出发地
			singleOrderEntity.setDeparture(startAddress);
			//目的地
			singleOrderEntity.setDestination(endAddress);
			//出发地省
			singleOrderEntity.setDepartureProvince(departureProvince);
			//出发地市
			singleOrderEntity.setDepartureCity(departureCity);
			//出发地区
			singleOrderEntity.setDepartureArea(departureArea);
			//目的地省
			singleOrderEntity.setDestinationProvince(destinationProvince);
			//目的地市
			singleOrderEntity.setDestinationCity(destinationCity);
			//目的地区
			singleOrderEntity.setDestinationArea(destinationArea);
			
			singleOrderEntity.setLongitude(longitude);
			singleOrderEntity.setLatitude(latitude);
			singleOrderEntity.setDeLongitude(deLongitude);
			singleOrderEntity.setDeLatitude(deLatitude);
			singleOrderEntity.setCancelFlag("0");
			

			JSONObject dateJsonObj=new JSONObject(dataMap);
			logger.info("预约代驾单下单接口接口请求报文[未加密] ==" + dateJsonObj.toString());
			String key = apiConfigUtil.getApiConfig(provider, "drive_decode");
			String key3Des = apiConfigUtil.getApiConfig(provider, "store_key3Des");
			String encryptDateStr = DriveDESUtil.driverEncrypt(dateJsonObj.toString(), key,key3Des);
			requestMap.put("source", source);
			requestMap.put("data", encryptDateStr);
			JSONObject requestJsonObj=new JSONObject(requestMap);

			Date requestDate = new Date();
	        // 调用预约代驾单下单接口
			String createBespeakOrderUrl = apiConfigUtil.getApiConfig(provider, "drive_create");
			
			logger.info("预约代驾单下单接口接口url ==" + createBespeakOrderUrl);
			logger.info("预约代驾单下单接口接口请求报文 ==" + requestJsonObj.toString());
			
	    	String packageResult = HttpClientUtil.sendHttpPost(createBespeakOrderUrl, requestJsonObj.toString(), new HashMap<String, String>(){{
	            put("Content-Type", "application/json;charset=UTF-8");
	        }});
	    	Date responseDate = new Date();
	    	JSONObject resultObject = JSONObject.parseObject(packageResult);
	    	Map<String, Object> responseBodyMap = resultObject.toJavaObject(Map.class);
	    	//响应码
	    	String resultCode = (String) responseBodyMap.get("resultCode");
	    	//代驾单状态
	    	String status = "";
	    	//接口请求结果
	    	String result = "";
	    	//轨迹描述
	    	String trackDesc = "";
	    	if(resultCode.equals("success")){
	    		status = "01";
	    		result = "1";
	    		trackDesc = "预约提交成功";
	    	}else{
	    		status = "00";
	    		result = "0";
	    		trackDesc = "预约提交失败";
	    	}

	    	singleOrderEntity.setStatus(status);
	    	singleOrderEntity.setUpdateTime(new Date());
	    	singleOrderEntity.setUpdater("system");
	    	singleOrderDao.updateByEntity(singleOrderEntity);
	    	
	    	SingleRecordEntity singleRecordEntity = new SingleRecordEntity();
	    	singleRecordEntity.setOrderNo(orderNo);
	    	singleRecordEntity.setOrderId(couponNum);
	    	singleRecordEntity.setInterfaceName("单项代驾类预约接口");
	    	singleRecordEntity.setRequestTime(requestDate);
	    	singleRecordEntity.setRequestEncryptBody(requestJsonObj.toString());
	    	singleRecordEntity.setRequestBody(dateJsonObj.toString());
	    	singleRecordEntity.setResponseBody(packageResult);
	    	singleRecordEntity.setResponseTime(responseDate);
	    	singleRecordEntity.setCreateTime(new Date());
	    	singleRecordDao.insertVo(singleRecordEntity);
	    	
	    	LoginAuthDto loginUser = RequestUtil.getLoginUser();
	    	saveTrack(storeCouponEntity, "2", trackDesc, result, loginUser.getUserCode());
	    	
	    	return resultObject;
		} catch (Exception e) {
			logger.info("请求单项代驾类预约接口异常"+e.getMessage());
			jsonResult.put("resultCode", "01");
    		jsonResult.put("resultDesc", "请求单项代驾类预约接口异常");
            return jsonResult;
		}
	}

	/**
	 * @param reqVo
	 * @return
	 * @description 根据参数，保存单项到店类卡券的门店信息等
	 * @author wkangle
	 * @time 2022/04/07 0007 14:33
	 * @exception/throws
	 */
	@Override
	public JSONObject createStoreAppointment(Map<String, Object> reqVo) {
		JSONObject jsonResult = new JSONObject();
		if (PublicUtil.isEmpty(reqVo.get("storeInfoId"))) {
			jsonResult.put("code", "9999");
			jsonResult.put("msg", "门店主键为空，请重新选择");
			return jsonResult;
		}
		if (PublicUtil.isEmpty(reqVo.get("orderId"))) {
			jsonResult.put("code", "9999");
			jsonResult.put("msg", "卡券编码为空，请重新联系管理员");
			return jsonResult;
		}
		if (PublicUtil.isEmpty(reqVo.get("activityId"))) {
			jsonResult.put("code", "9999");
			jsonResult.put("msg", "服务项目编号为空，请重新联系管理员");
			return jsonResult;
		}
		String storeInfoId = reqVo.get("storeInfoId").toString();
		String orderId = reqVo.get("orderId").toString();
		String activityId = reqVo.get("activityId").toString();

		SingleOrderEntity singleOrderEntity = null;
		LoginAuthDto loginUser = RequestUtil.getLoginUser();

		Map<String, Object> couponParams = new HashMap<>();
		couponParams.put("couponNum", orderId);
		StoreCouponEntity storeCouponEntity = storeCouponDao.getOneByParams(couponParams);

		if (PublicUtil.isEmpty(reqVo.get("id"))) { // 主键空，新增
			singleOrderEntity = new SingleOrderEntity();
			//String orderNo = orderNoGenerateUtil.getOrderNoByParamAndSourceCode("ZXDD", "00"); // TODO
			//singleOrderEntity.setOrderNo(orderNo);
			singleOrderEntity.setOrderId(orderId);
			singleOrderEntity.setStoreInfoId(storeInfoId);
			singleOrderEntity.setActivityId(activityId);
			singleOrderEntity.setServiceType("4"); // 服务类型  1-安全检测；2-代办年检；3-代驾 ；4-洗车
			singleOrderEntity.setStatus("01");
			Date currentDate = new Date();
			singleOrderEntity.setCreateTime(currentDate);
			singleOrderEntity.setUpdateTime(currentDate);
			singleOrderEntity.setCreater(loginUser.getUserCode());
			singleOrderEntity.setUpdater(loginUser.getUserCode());

			singleOrderDao.insert(singleOrderEntity);
			saveTrack(storeCouponEntity, "0", MsgConstant.successBookingInsert, "1", loginUser.getUserCode());
			jsonResult.put("code", "0000");
			jsonResult.put("msg", "门店保存成功");
			return jsonResult;
		} else { // 主键非空，修改
			Map<String, Object> orderParams = new HashMap<>();
			orderParams.put("id", reqVo.get("id").toString());
			singleOrderEntity = singleOrderDao.getOneByParams(orderParams);
			singleOrderEntity.setUpdateTime(new Date());
			singleOrderEntity.setStoreInfoId(storeInfoId);
			singleOrderEntity.setUpdater(loginUser.getUserCode());

			singleOrderDao.updateById(singleOrderEntity);
			saveTrack(storeCouponEntity, "0", MsgConstant.successBookingUpdate, "1", loginUser.getUserCode());

			jsonResult.put("code", "0000");
			jsonResult.put("msg", "门店修改成功");
			return jsonResult;
		}
	}

	/**
	 * 新增卡券使用轨迹
	 * @param couponEntity  卡券信息
	 * @param trackType 轨迹类型：0-车服内部，1-与上游交互，2-与下游交互，3-与商户端交互
	 * @param trackDesc 轨迹描述
	 * @param result 接口请求结果：0-失败，1-成功
	 * @param creater
	 */
	 private void saveTrack(StoreCouponEntity couponEntity, String trackType, String trackDesc, String result, String creater){
		 Date d = new Date();
		 SingleCouponTrackEntity vo = new SingleCouponTrackEntity(couponEntity.getId(),couponEntity.getCouponNum(),
				 trackType,trackDesc,couponEntity.getStatus(),result);
		 vo.setIsDelete(0);
		 vo.setCreateTime(d);
		 vo.setCreater(creater);
		 vo.setUpdateTime(d);
		 vo.setUpdater(creater);
		 singleCouponTrackDao.insert(vo);
	 }

	/**
	 * @param reqVo
	 * @return
	 * @description 根据卡券编码、服务项目编号，查询到店类卡券预约信息
	 * @author wkangle
	 * @time 2022/04/07 0007 10:42
	 * @exception/throws
	 */
	@Override
	public Map<String, Object> queryBookingInfo(Map<String, Object> reqVo) {
		String couponNum = PublicUtil.isNotEmpty(reqVo.get("couponNum")) ? reqVo.get("couponNum").toString() : null;
		Map<String, Object> result = new HashMap<>();

		// 服务项目名称
		String activityId = PublicUtil.isNotEmpty(reqVo.get("activityId")) ? reqVo.get("activityId").toString() : null;
		Map<String, Object> codeParams = new HashMap<String, Object>();
		codeParams.put("typeCode", "singleActivityName");
		codeParams.put("code", activityId);
		DictCodeEntity dictCodeEntity = dictCodeService.getOneByParams(codeParams);
		result.put("activityName", dictCodeEntity.getValue());

		// 预约基本信息
		reqVo.put("orderId", reqVo.get("couponNum"));
		SingleOrderEntity singleOrderEntity = singleOrderDao.getOneByParams(reqVo); // 预约信息
		System.out.println(singleOrderEntity.getStoreInfoId());
		Long id = singleOrderEntity != null ? singleOrderEntity.getId() : null; // 服务单主键id
		result.put("id", id);
		String storeInfoId = singleOrderEntity != null ? singleOrderEntity.getStoreInfoId() : null; // 服务单记录的门店id
		Map<String, Object> storeInfoParams = new HashMap<>();
		storeInfoParams.put("id", storeInfoId);
		StoreInfoEntity storeInfoEntity = storeInfoId != null ? storeInfoService.getOneByParams(storeInfoParams) : null; // 预约的门店信息
		logger.info("storeInfoEntity ==> {}", storeInfoEntity);
		if (storeInfoEntity != null) {
			result.put("shopName", storeInfoEntity.getShopName()); // 店名
			result.put("businessHours", storeInfoEntity.getOpenTime() + " - " + storeInfoEntity.getRestTime()); // 营业时间
			result.put("detailAddress", storeInfoEntity.getAddress()); // 地址
			result.put("telephone", storeInfoEntity.getTelephone()); // 联系电话

			// 门店坐标
			String coordinate = storeInfoEntity.getCoordinate();
			String[] split = coordinate.split(",");

			// 计算门店和当前坐标的距离
			Double currentLatitude = PublicUtil.isNotEmpty(reqVo.get("currentLatitude")) ? Double.valueOf(reqVo.get("currentLatitude").toString()) : null; // 当前坐标纬度
			Double currentLongitude = PublicUtil.isNotEmpty(reqVo.get("currentLongitude")) ? Double.valueOf(reqVo.get("currentLongitude").toString()) : null; // 当前坐标经度
			System.out.println("currentLatitude: " + currentLatitude);
			System.out.println("currentLongitude: " + currentLongitude);
			GlobalCoordinates source = new GlobalCoordinates(currentLatitude, currentLongitude);
			GlobalCoordinates target = new GlobalCoordinates(Double.valueOf(split[1]), Double.valueOf(split[0]));
			double sphereMeter = getDistanceMeter(source, target, Ellipsoid.Sphere);
			result.put("sphereMeter", sphereMeter); // 距离
			logger.info("if:single_queryBookingInfo_result_storeinfo ==> {}", result);
		} else {
			List<StoreInfoVo> storeInfoVos = storeInfoService.queryStoreList(reqVo);
			if (storeInfoVos != null && storeInfoVos.size() > 0) {
				StoreInfoVo storeInfoVo = storeInfoVos.get(0);
				result.put("shopName", storeInfoVo.getShopName()); // 店名
				result.put("businessHours", storeInfoVo.getBusinessHours()); // 营业时间
				result.put("detailAddress", storeInfoVo.getDetailAddress()); // 地址
				result.put("telephone", storeInfoVo.getTelephone()); // 联系电话
				result.put("sphereMeter", storeInfoVo.getSphereMeter()); // 距离
				logger.info("else:single_queryBookingInfo_result_storeinfo ==> {}", result);
			}
		}

		// 卡券基本信息
		Map<String, Object> couponParams = new HashMap<>();
		couponParams.put("couponNum", couponNum);
		StoreCouponEntity storeCouponEntity = storeCouponDao.getOneByParams(couponParams);

		result.put("expDate", storeCouponEntity != null ? new SimpleDateFormat("yyyy-MM-dd").format(storeCouponEntity.getExpDate()) : null); // 失效时间

		// 二维码
		Map<String, Object> couponQRResult = storeCouponService.couponQR(couponNum);
		if ("0000".equals(couponQRResult.get("code"))) {
			result.put("qr", couponQRResult.get("message")); // 二维码
		}

		logger.info("single_queryBookingInfo_result ==> {}", result);
		return result;
	}

	/**
	 * @param reqVo
	 * @return
	 * @description 根据用户输入的地址查询对应的坐标，用于搜索门店列表
	 * @author wkangle
	 * @time 2022-04-11 13:44:38
	 * @exception/throws
	 */
	@Override
	public Map<String, Object> querySearchAddress(Map<String, Object> reqVo) {
		String coordinate = AddressUtil.getCoordinate(reqVo.get("searchAddress").toString(), reqVo.get("cityName").toString());
		//String gcj02From5To3 = AddressUtil.getGcj02From5To3(coordinate); // 百度坐标转为火星坐标
		Map<String, Object> result = new HashMap<>();
		String[] split = coordinate.split(",");
		result.put("longitude", split[0]);
		result.put("latitude", split[1]);
		return result;
	}

	/**
	 * @param reqVo
	 * @return
	 * @description 根据用户输入的地址查询地址信息，用于获取代驾出发地、目的地详细信息
	 * @author wkangle
	 * @time 2022-04-11 13:44:38
	 * @exception/throws
	 */
	@Override
	public Map<String, Object> queryDrivingAddress(Map<String, Object> reqVo) {
		String coordinate = AddressUtil.getCoordinate(reqVo.get("searchAddress").toString(), reqVo.get("cityName").toString());
		Map<String, Object> addressListByCoordinate = AddressUtil.getAddressListByCoordinate(coordinate.split(",")[1] + "," + coordinate.split(",")[0]);
		return addressListByCoordinate;
	}

	/**
	 * @param reqVo
	 * @return
	 * @description 查询代驾单信息
	 * @author wkangle
	 * @time 2022/04/12 0012 13:01
	 * @exception/throws
	 */
	@Override
	public SingleOrderVo drivingProgress(Map<String, Object> reqVo) {
		logger.info(new Date() + ": =====drivingProgress====== " + reqVo);
		// 预约代驾服务单信息
		Map<String, Object> params = new HashMap<>();
		params.put("couponNum", reqVo.get("couponNum"));
		params.put("carNo", reqVo.get("carNo"));
		return singleOrderDao.getByParams(params);
	}

	/**
	 * @param reqVo
	 * @return
	 * @description 单项代驾取消
	 * @author wkangle
	 * @time 2022/04/13 0013 13:56
	 * @exception/throws
	 */
	@Override
	public Map<String, String> driverCancel(Map<String, String> reqVo) {
		Map<String, String> resultMap = new HashMap<>();
		String orderNo = reqVo.get("orderNo");
		String orderId = reqVo.get("orderId");
		if(PublicUtil.isEmpty(orderNo)) {
			resultMap.put("code", "01");
			resultMap.put("msg", "服务单号orderNo不能为空");
			return resultMap;
		}
		if(PublicUtil.isEmpty(orderId)) {
			resultMap.put("code", "01");
			resultMap.put("msg", "订单号orderId不能为空");
			return resultMap;
		}

		// 预约代驾服务单信息
		Map<String, Object> params = new HashMap<>();
		params.put("couponNum", orderId);
		SingleOrderVo singleOrderVo = this.drivingProgress(params);
		if(singleOrderVo == null){
			resultMap.put("code", "01");
			resultMap.put("msg", "代驾订单不存在");
			return resultMap;
		}
		String cancelFlag = singleOrderVo.getCancelFlag(); //取消标识，0-可取消、1-不可取消
		if(PublicUtil.isNotEmpty(cancelFlag) && "1".equals(cancelFlag)) {
			resultMap.put("code", "01");
			resultMap.put("msg", "代驾订单不可重复取消");
			return resultMap;
		}

		SingleRecordEntity singleRecordEntity = new SingleRecordEntity();
		Map<String,Object> requestBody = new HashMap<String,Object>();

		StoreCouponEntity storeCouponEntity = storeCouponDao.getOneByParams(params);
		String provider = storeCouponEntity.getServer();

		String source = apiConfigUtil.getApiConfig(provider, "disponse_code");
		requestBody.put("source", source);
		Map<String,String> encry = new HashMap<String,String>();
		encry.put("source", source);
		encry.put("orderId", orderId);
		String requestEncryptBody = "";
		try {
			String key = apiConfigUtil.getApiConfig(provider, "drive_decode");
			String key3Des = apiConfigUtil.getApiConfig(provider, "store_key3Des");
			String data = DriveDESUtil.driverEncrypt(CommonUtils.toJSONString(encry), key,key3Des);
			requestBody.put("data", data);
			singleRecordEntity.setOrderId(orderId);
			singleRecordEntity.setOrderNo(orderNo);
			singleRecordEntity.setInterfaceName("代驾取消接口");
			singleRecordEntity.setRequestTime(new Date());
			requestEncryptBody = CommonUtils.toJSONString(requestBody);
			String request = CommonUtils.toJSONString(encry);
			singleRecordEntity.setRequestBody(request);
			singleRecordEntity.setRequestEncryptBody(requestEncryptBody);
		} catch(Exception e){
			resultMap.put("code", "01");
			resultMap.put("msg", "代驾取消报文加密报错");
			return resultMap;
		}
		String cancelUrl = apiConfigUtil.getApiConfig(provider, "annInsp_cancel");
		logger.info("代驾取消接口url ==" + cancelUrl);
		logger.info("代驾取消接口请求报文 ==" + requestEncryptBody);

		String resultJson = CommonUtils.driverPost(cancelUrl, requestEncryptBody);
		singleRecordEntity.setResponseTime(new Date());
		singleRecordEntity.setResponseBody(resultJson);
		singleRecordEntity.setCreateTime(new Date());
		singleRecordDao.insertVo(singleRecordEntity);

		LoginAuthDto loginUser = RequestUtil.getLoginUser();
		if(resultJson != null){
			try {
				JSONObject json = JSONObject.parseObject(resultJson);
				String resultCode = json.get("resultCode").toString();
				if("success".equals(resultCode)){ //调用成功
					//更新代驾单cancelFlag：0-可取消、1-不可取消 为1，防止用户多次取消
					Map<String, Object> orderParam = new HashMap<>();
					orderParam.put("orderNo", orderNo);//服务单号
					orderParam.put("cancelFlag", "1");
					singleOrderDao.updateByParams(orderParam);
					resultMap.put("code", "00");
					resultMap.put("msg", "代驾取消成功");
					saveTrack(storeCouponEntity, "0", "代驾取消成功", "1", loginUser.getUserCode());
				}else{
					resultMap.put("code", "01");
					Object resultDesc = json.get("resultDesc");
					String message = "";
					if(resultDesc!=null){
						message = resultDesc.toString();
					}
					resultMap.put("msg", "代驾取消失败:"+message);
					saveTrack(storeCouponEntity, "0", "代驾取消接口失败:"+message, "0", loginUser.getUserCode());
				}
			} catch (Exception e) {
				//返回参数格式有误，解析异常，记录轨迹
				resultMap.put("code", "01");
				resultMap.put("msg", "代驾取消失败:响应报文解析异常");
				saveTrack(storeCouponEntity, "0", "代驾取消接口失败:响应报文解析异常", "0", loginUser.getUserCode());
			}
		}else{
			resultMap.put("code", "01");
			resultMap.put("msg", "代驾取消失败:响应报文为空");
			saveTrack(storeCouponEntity, "0", "代驾取消接口失败:响应报文为空", "0", loginUser.getUserCode());
		}
		return resultMap;
	}

	// 计算距离
	public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) {
		//创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
		GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
		return geoCurve.getEllipsoidalDistance();
	}
}
